/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.inspur.edp.metadata.service.dev.core.manager;

import com.inspur.edp.lcm.metadata.api.exception.DuplicateImplementationException;
import com.inspur.edp.lcm.metadata.api.exception.ErrorCodes;
import com.inspur.edp.lcm.metadata.spi.MetadataChangeSetService;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 元数据变更集服务工厂类
 */
@Slf4j
public class MetadataChangeSetServiceFactory {
    private static final Map<String, MetadataChangeSetService> metadataChangeSetServiceMap = new ConcurrentHashMap<>();

    public static MetadataChangeSetService getMetadataChangeSetService(String metadataType) {
        if (CollectionUtils.isEmpty(metadataChangeSetServiceMap)) {
            // 汇总所有的SPI实现类
            Map<String, MetadataChangeSetService> serviceMap = SpringBeanUtils.getApplicationContext().getBeansOfType(MetadataChangeSetService.class);
            Map<String, MetadataChangeSetService> tempMap = new HashMap<>();
            // 根据SPI实现类指定其对应的元数据类型,构造哈希表. 若出现元数据类型重复则抛出异常
            serviceMap.values()
                    .forEach(service -> {
                        MetadataChangeSetService metadataChangeSetService = tempMap.putIfAbsent(service.getMetadataType(), service);
                        if (metadataChangeSetService != null) {
                            throw new DuplicateImplementationException(ErrorCodes.ECP_DUP_IMPL_0001,
                                    "MetadataChangeSetService", "MetadataType", service.getMetadataType(),
                                    service.getClass().getName(), metadataChangeSetService.getClass().getName());
                        }
                    });
            metadataChangeSetServiceMap.putAll(tempMap);
        }
        return metadataChangeSetServiceMap.get(metadataType);
    }
}
